import React, {useState} from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, Switch, Link, matchPath} from 'react-router-dom';
import {createBrowserHistory} from 'history';
import * as Sentry from '@sentry/react';
import {Integrations} from '@sentry/tracing';
import {createStore} from 'redux';
import SentryRRWeb from '@sentry/rrweb';

const history = createBrowserHistory();

const routes = [{path: '/about'}, {path: '/user/:id'}, {path: '/'}];

Sentry.init({
  dsn: 'http://6af3eadd87d14f02aa79da6e1cecddbc@106.15.234.106:9000/2',
  environment: 'localhost',
  // integrations: [new Integrations.BrowserTracing()],
  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for performance monitoring.
  // We recommend adjusting this value in production
  integrations: [
    new Integrations.BrowserTracing({
      routingInstrumentation: Sentry.reactRouterV5Instrumentation(history, routes, matchPath),
    }),
    new SentryRRWeb({
      checkoutEveryNms: 10 * 1000, // 每10秒重新制作快照
      checkoutEveryNth: 200, // 每 200 个 event 重新制作快照
      maskAllInputs: false, // 将所有输入内容记录为 *
    }),
  ],
  tracesSampleRate: 1.0,
  release: '0.0.1',
  debug: true,
});


Sentry.addBreadcrumb({
  category: "auth",
  message: "Authenticated user 18334860056@163.com",
  level: Sentry.Severity.Info,
});


const initialState = {
  a: 'init',
  b: 'init',
  c: 'init',
};

const rootReducer = (state = initialState, action) => {
  if (action.type === 'SET_A') {
    return {
      ...state,
      a: 'a_changed',
    }
  }
  if (action.type === 'SET_B') {
    return {
      ...state,
      b: 'b_changed',
    }
  }
  if (action.type === 'SET_C') {
    return {
      ...state,
      c: 'c_changed',
    }
  }
  return state;
}


// 通过 sentryReduxEnhancer 中的 actionTransformer 和 stateTransformer 过滤不需要在sentry管理界面中展示的 action 和 state
const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  actionTransformer: action => {
    if (action.type === 'SET_B') {
      return null;
    }
    return action;
  },
  stateTransformer: state => {
    return {
      ...state,
      c: null,
    }
  },
});


const store = createStore(
  rootReducer,
  sentryReduxEnhancer,
);

// const App = () => {
//   function fn() {
//     console.log(window.a.d);
//   }
//   return (
//     <Router history={history}>
//       <>
//         <nav>
//           <ul>
//             <li>
//               <Link to="/">Home</Link>
//             </li>
//             <li>
//               <Link to="/about">About</Link>
//             </li>
//             <li>
//               <Link to="/user/1">User1</Link>
//             </li>
//             <li>
//               <Link to="/user/2">User2</Link>
//             </li>
//           </ul>
//         </nav>
//         <Switch>
//           <Route path="/about" children={
//             () => <div>about</div>
//           } />
//           <Route path="/user/:id" children={
//             () => <div>user</div>
//           } />
//           <Route exact path="/" children={
//             () => <button onClick={fn}>Break the world</button>
//           } />
//         </Switch>
//       </>
//     </Router>
//   );
// }


const App = () => {
  function fn() {
    console.log(window.a.b);
    // axios.get('/dddd').catch(() => {});
  }
  return (
    <>
      <button onClick={() => store.dispatch({type: 'SET_A'})}>dispatch SET_A</button>
      <button onClick={() => store.dispatch({type: 'SET_B'})}>dispatch SET_B</button>
      <button onClick={() => store.dispatch({type: 'SET_C'})}>dispatch SET_C</button>
      <button onClick={fn}>Break the world</button>

      <Router history={history}>
        <>
          <nav>
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to="/about">About</Link>
              </li>
              <li>
                <Link to="/user/1">User1</Link>
              </li>
              <li>
                <Link to="/user/2">User2</Link>
              </li>
            </ul>
          </nav>
          <Switch>
            <Route path="/about" children={
              () => <div>about</div>
            } />
            <Route path="/user/:id" children={
              () => <div>user</div>
            } />
            <Route exact path="/" children={
              () => <button onClick={fn}>Break the world</button>
            } />
          </Switch>
        </>
      </Router>

    </>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);


// 对于未捕获的异常，我们可以手动上报。 官方文档

// try {
//   aFunctionThatMightFail22();
// } catch (err) {
//   Sentry.captureException(err, {
//     level: Sentry.Severity.Warning,
//   });
// }
// // 另外我们还可以手动上报一些纯文本信息

// Sentry.captureMessage("手动上报错误定义 level", Sentry.Severity.Debug);


// // 定义一个范围，在范围内容统一定义 level
// Sentry.configureScope(function (scope) {
//   scope.setLevel(Sentry.Severity.Error);
//   aFunctionThatMightFail33();
//   bFunctionThatMightFail444();
// });



// const App = () => {
//   function fn() {
//     console.log(window.a.d);
//   }
//   return (
//     <Router history={history}>
//       <>
//         <nav>
//           <ul>
//             <li>
//               <Link to="/">Home</Link>
//             </li>
//             <li>
//               <Link to="/about">About</Link>
//             </li>
//             <li>
//               <Link to="/user/1">User1</Link>
//             </li>
//             <li>
//               <Link to="/user/2">User2</Link>
//             </li>
//           </ul>
//         </nav>
//         <Switch>
//           <Route path="/about" children={
//             () => <div>about</div>
//           } />
//           <Route path="/user/:id" children={
//             () => <div>user</div>
//           } />
//           <Route exact path="/" children={
//             () => <button onClick={fn}>Break the world</button>
//           } />
//         </Switch>
//       </>
//     </Router>
//   );
// }

// ReactDOM.render(
//   <React.StrictMode>
//     <App />
//   </React.StrictMode>,
//   document.getElementById('root')
// );


// const App = () => {
//   const [error, setError] = useState(false);
//   return (
//     <>
//       {error && new Error('error')}
//       <button onClick={() => setError(true)}>set error</button>
//     </>
//   );
// }
// const WithSentryErrorBoundaryApp = () => {
//   return (
//     <Sentry.ErrorBoundary fallback={<div>error boundary error</div>} showDialog>
//       <App />
//     </Sentry.ErrorBoundary>
//   );
// }

// // 也可以使用Sentry提供的高阶组件 withErrorBoundary 实现同样效果
// // https://docs.sentry.io/platforms/javascript/guides/react/components/errorboundary/
// const WithSentryApp = Sentry.withErrorBoundary(App, {fallback: <p>an error has occurred</p>, showDialog: true});

// ReactDOM.render(
//   // <WithSentryErrorBoundaryApp />,
//   <WithSentryApp />,
//   document.getElementById('root')
// );